x86 shadow: fix race when domain is dying
authorKeir Fraser <keir.fraser@citrix.com>
Thu, 26 Nov 2009 11:02:30 +0000 (11:02 +0000)
committerKeir Fraser <keir.fraser@citrix.com>
Thu, 26 Nov 2009 11:02:30 +0000 (11:02 +0000)
There are some cases that shadow_write_p2m_entry() is called after
the domain is killed. It causes Xen to crash.

- Race between xc_map_foreign_batch from qemu-dm and "xm destroy"
  command.
- The hypervisor calls domain_crash when PoD fails.

Signed-off-by: Kouya Shimura <kouya@jp.fujitsu.com>
xen/arch/x86/mm/p2m.c
xen/arch/x86/mm/shadow/common.c

index aebfdd18a6e75bd71826c7ace1065f0307eef77c..e916d46faf9080d132e2965c18693342868add02 100644 (file)
@@ -1221,6 +1221,12 @@ p2m_gfn_to_mfn(struct domain *d, unsigned long gfn, p2m_type_t *t,
 
     ASSERT(paging_mode_translate(d));
 
+    if ( unlikely(d->is_dying) )
+    {
+        *t = p2m_invalid;
+        return _mfn(INVALID_MFN);
+    }
+
     /* XXX This is for compatibility with the old model, where anything not 
      * XXX marked as RAM was considered to be emulated MMIO space.
      * XXX Once we start explicitly registering MMIO regions in the p2m 
index 94457a328186a4a41ab22987eaa49a2afd5495ec..f6cc319f86d4968c568dd5157985288851c75b3d 100644 (file)
@@ -2171,6 +2171,7 @@ static void hash_foreach(struct vcpu *v,
 
     /* Say we're here, to stop hash-lookups reordering the chains */
     ASSERT(shadow_locked_by_me(d));
+    ASSERT(d->arch.paging.shadow.hash_table);
     ASSERT(d->arch.paging.shadow.hash_walking == 0);
     d->arch.paging.shadow.hash_walking = 1;
 
@@ -3449,6 +3450,12 @@ shadow_write_p2m_entry(struct vcpu *v, unsigned long gfn,
     
     shadow_lock(d);
 
+    if ( unlikely(d->is_dying) )
+    {
+        shadow_unlock(d);
+        return;
+    }
+
     /* If we're removing an MFN from the p2m, remove it from the shadows too */
     if ( level == 1 )
     {